home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / sunprom / sync.h.save < prev    next >
Encoding:
Text File  |  1989-06-13  |  11.7 KB  |  449 lines

  1. /*
  2.  * sync.h --
  3.  *
  4.  *     Definitions of the synchronization module.
  5.  *     The synchronization module provides locks and condition
  6.  *     variables to other modules, plus a low level binary semaphore 
  7.  *    needed to synchronize with interrupt handlers.
  8.  *
  9.  * Copyright 1986 Regents of the University of California
  10.  * All rights reserved.
  11.  *
  12.  * $Header: /sprite/src/kernel/sync/RCS/sync.h,v 8.11 89/04/06 12:09:40 jhh Exp $ SPRITE (Berkeley)
  13.  */
  14.  
  15. #ifndef _SYNC
  16. #define _SYNC
  17.  
  18. #include "sprite.h"
  19. #include "list.h"
  20. #include "boot.h"
  21. #ifdef KERNEL
  22. #include "proc.h"
  23. #include "user/sync.h"
  24. #include "sys.h"
  25. #include "mach.h"
  26. #else
  27. #include <sync.h>
  28. #include <kernel/sys.h>
  29. #include <kernel/proc.h>
  30. #include <kernel/mach.h>
  31. #endif /* */
  32.  
  33. /*
  34.  * Flags for syncFlags field in the proc table:
  35.  *
  36.  *  SYNC_WAIT_REMOTE            - The process is on a wait list somewhere on
  37.  *                                some host and will block until it gets a
  38.  *                                wakeup message.
  39.  *  SYNC_WAIT_COMPLETE          - The process was doing a remote wait and
  40.  *                                it has received a wakeup message.
  41.  */
  42.  
  43. #define    SYNC_WAIT_COMPLETE    0x1
  44. #define    SYNC_WAIT_REMOTE    0x2
  45.  
  46. /*
  47.  * Definitions of variables for instrumentation.
  48.  */
  49.  
  50. typedef struct Sync_Instrument {
  51.     int numWakeups;        /* number of wakeups performed */
  52.     int numWakeupCalls;        /* number of calls to wakeup */
  53.     int numSpuriousWakeups;    /* number of incorrectly awakened sleeps */
  54.     int numLocks;        /* number of calls to MASTER_LOCK */
  55.     int numUnlocks;        /* number of calls to MASTER_UNLOCK */
  56. } Sync_Instrument;
  57.  
  58. /*
  59.  * This is used inside the Sync_Semaphore and Sync_Lock structures to allow
  60.  * them to be linked into lists. Usually the links field is first in a
  61.  * structure so that the list routines work correctly. The CLEAN_LOCK
  62.  * version of locks do not use the links field and expect the value of
  63.  * the lock to be the first field. The easiest solution is to put the
  64.  * links inside a structure which in turn is inside the locks. The linked
  65.  * list elements are these inner structures, which in turn have a pointer
  66.  * to the lock that contains them.
  67.  */
  68. typedef struct Sync_ListInfo {
  69.     List_Links    links;        /* used to link into lists */
  70.     Address    lock;        /* ptr at outer structure that contains this
  71.                  * structure */
  72. } Sync_ListInfo;
  73.  
  74. /*
  75.  * Classes of locks. The "class" field of both locks and semaphores is 
  76.  * at the same offset within the structures. This allows routines to determine
  77.  * the class of a parameter.
  78.  */
  79. typedef enum Sync_LockClass {
  80.     SYNC_SEMAPHORE,            
  81.     SYNC_LOCK
  82. } Sync_LockClass;
  83.  
  84. /*
  85.  *  Maximum types of locks. Types are assigned as locks are registered, 
  86.  *  starting at 1. No distiction is made between locks and semaphores when
  87.  *  assigning a type. The type is used as an index into the array of
  88.  *  statistics for that lock type. Unregistered locks have a type of 0,
  89.  *  and the type of the lock that protects the lock registration itself is
  90.  *  -1. We have to treat this lock specially because a lock is registered
  91.  *  after it is locked, and we need to lock the registration lock in order
  92.  *  to register a lock. Hence we can't register the registration lock.
  93.  */
  94.  
  95. #define SYNC_MAX_LOCK_TYPES 50
  96.  
  97. /*
  98.  * Semaphore structure
  99.  */
  100. typedef struct Sync_Semaphore {
  101.     /*
  102.      * The value field must be first.
  103.      */
  104.     int value;                /* value of semaphore */
  105. } Sync_Semaphore;
  106.  
  107. typedef struct Sync_KernelLock{
  108.     /*
  109.      * The inUse and waiting fields must be first and in this order.
  110.      */
  111.     Boolean inUse;            /* 1 while the lock is busy */
  112.     Boolean waiting;                /* 1 if someone wants the lock */
  113. } Sync_KernelLock;
  114.  
  115. #ifdef KERNEL
  116. typedef Sync_KernelLock Sync_Lock;    /* define locks for kernel */
  117. #endif
  118.  
  119.  
  120. /*
  121.  * Define a structure to keep track of waiting processes on remote machines.
  122.  */
  123.  
  124. typedef struct {
  125.     List_Links    links;        /* Link info about related waiting processes */
  126.     int        hostID;        /* Host ID of waiting process */
  127.     Proc_PID    pid;        /* ID of waiting process */
  128.     int        waitToken;    /* Local time stamp used to catch races */
  129. } Sync_RemoteWaiter;
  130.  
  131. /*
  132.  * Wait token value used to wakeup a process regardless of its value of
  133.  * the wait token.
  134.  */
  135. #define    SYNC_BROADCAST_TOKEN    -1
  136.  
  137. /*
  138.  * Exported procedures and variables of the sync module.
  139.  */
  140.     
  141.  
  142. extern     void         Sync_Init();
  143.  
  144. extern     void         Sync_WakeupProcess();
  145. extern     void         Sync_EventWakeup();
  146. extern     void         Sync_WakeWaitingProcess();
  147. extern     void         Sync_UnlockAndSwitch();
  148.  
  149. extern     Boolean     Sync_SlowMasterWait();
  150. extern     Boolean     Sync_SlowWait();
  151. extern     Boolean     Sync_EventWait();
  152. extern     Boolean     Sync_WaitTime();
  153. extern     Boolean     Sync_WaitTimeInTicks();
  154. extern     Boolean     Sync_WaitTimeInterval();
  155.  
  156. extern     Boolean     Sync_ProcWait();
  157. extern     void         Sync_ProcWakeup();
  158. extern     void         Sync_GetWaitToken();
  159. extern     void         Sync_SetWaitToken();
  160. extern     ReturnStatus     Sync_RemoteNotify();
  161. extern     ReturnStatus     Sync_RemoteNotifyStub();
  162.     
  163. extern     ReturnStatus     Sync_SlowLockStub();
  164. extern     ReturnStatus     Sync_SlowWaitStub();
  165. extern     ReturnStatus     Sync_SlowBroadcastStub();
  166.  
  167. extern     void         Sync_PrintStat();
  168.  
  169. extern    void        Sync_LockStatInit();
  170. extern    void        SyncAddPriorLock();
  171. extern    void        SyncDeleteCurrentLock();
  172. extern     void        SyncMergePriorLocks();
  173. extern    void        Sync_RegisterAnyLock();
  174. extern    void        Sync_CheckoutAnyLock();
  175. extern    void        Sync_PrintLockStats();
  176.  
  177.  
  178. /*
  179.  * If CLEAN_LOCK is defined then don't register locks and don't keep track
  180.  * of lock dependency pairs.
  181.  */
  182. #ifdef CLEAN_LOCK
  183. #undef LOCKREG
  184. #undef LOCKDEP
  185. #endif
  186.  
  187. /*
  188.  * If LOCKDEP is  defined then we need to register locks.
  189.  */
  190. #ifdef LOCKDEP
  191. #define LOCKREG
  192. #endif
  193.  
  194.  
  195.  
  196. /*
  197.  *----------------------------------------------------------------------------
  198.  *
  199.  * MASTER_LOCK --
  200.  *
  201.  *    Enter a critical section guarded by a binary semaphore.
  202.  *    This is for use in a multiprocessor environment
  203.  *    within the synchronization module, and in other
  204.  *    modules that interact with interrupt-time routines.
  205.  *    (All other synchronization should be done with Monitors.)
  206.  *    
  207.  *    Interrupts are disabled on the local processor to prevent
  208.  *    a preemptive context switch.  The semaphore is checked
  209.  *    with a Mach_TestAndSet atomic operation in a busy wait
  210.  *    to prevent races with other processors.
  211.  *
  212.  *
  213.  * For uniprocessor debugging, panic when the lock is held (otherwise
  214.  * we get an infinite loop).
  215.  *
  216.  * Results:
  217.  *     None.
  218.  *
  219.  * Side effects:
  220.  *    The semaphore has its value set from 0 to 1.
  221.  *    Interrupts are disabled.
  222.  *
  223.  *----------------------------------------------------------------------------
  224.  */
  225.  
  226. #define MASTER_LOCK(semaphore) 
  227. /*
  228.  *----------------------------------------------------------------------------
  229.  *
  230.  * MASTER_UNLOCK --
  231.  *
  232.  *    Leave a critical section guarded by a binary semaphore.  This is for
  233.  *    use in a multiprocessor environment.  Interrupts are enabled and the
  234.  *    semaphore value is reset to 0 to allow other processors entry into
  235.  *    the critical section.
  236.  *
  237.  * Results:
  238.  *     None.
  239.  *
  240.  * Side effects:
  241.  *    The semaphore has its value reset to 0.
  242.  *    Interrupts are enabled.
  243.  *
  244.  *----------------------------------------------------------------------------
  245.  */
  246.  
  247. #define MASTER_UNLOCK(semaphore) 
  248.  
  249.  
  250. /* 
  251.  * Condition variables can be used in critical sections guarded by
  252.  * MASTER_LOCK and MASTER_UNLOCK.  Sync_MasterWait and
  253.  * Sync_MasterBroadcast are the analogues of Sync_Wait and
  254.  * Sync_Broadcast.
  255.  */
  256.  
  257. /*
  258.  *----------------------------------------------------------------------
  259.  *
  260.  * Sync_MasterWait --
  261.  *
  262.  *    Wait on an event with a master lock held.
  263.  *    This has the same semantics as Sync_Wait except
  264.  *    that the lock release when the process sleeps is
  265.  *    a master lock.
  266.  *
  267.  * Results:
  268.  *    None.
  269.  *
  270.  * Side effects:
  271.  *    The process gets descheduled, the master lock gets released
  272.  *    and then reacquired after the condition is notified.
  273.  *
  274.  *----------------------------------------------------------------------
  275.  */
  276.  
  277. #define Sync_MasterWait(conditionPtr, mutexPtr, wakeIfSignal) (boot_Poll)()
  278. /*
  279.  *----------------------------------------------------------------------
  280.  *
  281.  * Sync_MasterBroadcast --
  282.  *
  283.  *    Notify an event, like Sync_Broadcast except it
  284.  *    should be used with a master lock held because of the
  285.  *    check on conditionPtr->waiting.
  286.  *
  287.  *    (This could verify that a master lock is held.)
  288.  *
  289.  * Results:
  290.  *    None.
  291.  *
  292.  * Side effects:
  293.  *    Notify all processes waiting on the event.
  294.  *
  295.  *----------------------------------------------------------------------
  296.  */
  297.  
  298. #define Sync_MasterBroadcast(conditionPtr) 
  299.  
  300. /*
  301.  *----------------------------------------------------------------------
  302.  *
  303.  * UNLOCK_AND_SWITCH --
  304.  *
  305.  *    Macro to call the internal routine to release the monitor lock and
  306.  *    then context switch.
  307.  *
  308.  * Results:
  309.  *    None.
  310.  *
  311.  * Side effects:
  312.  *    Lock released and process context switched.
  313.  *
  314.  *----------------------------------------------------------------------
  315.  */
  316.  
  317. #define UNLOCK_MONITOR_AND_SWITCH(state) Sync_UnlockAndSwitch(LOCKPTR, state)
  318.  
  319. /*
  320.  *    The initialization routines are used to initialize a semaphore.
  321.  *    The name parameter is the name of the semaphore and is used to
  322.  *    distinguish between types of locks. If you want the statistics
  323.  *    (hit, miss, etc) for two semaphores to be shared then give them the
  324.  *    same name. An example might be locks around file handles, where it
  325.  *    makes more sense to have the statistics for all the locks as a whole,
  326.  *    rather than just one lock. Also beware that no distinction is made
  327.  *    between locks and semaphores when determining types -- if they have
  328.  *    the same name they have the same type.
  329.  *       Sync_SemClear should be called when a semaphore is being deallocated
  330.  *    and will be no longer used. Currently all this routine does is to
  331.  *    take the statistics associated with the semaphore and merge them in
  332.  *    with those for the type as a whole.
  333.  */
  334.  
  335. /*
  336.  *----------------------------------------------------------------------
  337.  *
  338.  * Sync_SemRegister --
  339.  *
  340.  * Obsolete.
  341.  *
  342.  *----------------------------------------------------------------------
  343.  */
  344. #define Sync_SemRegister Sync_LockRegister
  345.  
  346. /* 
  347.  *----------------------------------------------------------------------
  348.  *
  349.  * Sync_SemClear
  350.  * 
  351.  * Obsolete.
  352.  *
  353.  *----------------------------------------------------------------------
  354.  */
  355. #define Sync_SemClear Sync_LockClear
  356.  
  357.  
  358. /*
  359.  *----------------------------------------------------------------------
  360.  *
  361.  * Sync_SemInitStatic --
  362.  *
  363.  *    Initializes the fields of a semaphore in an initialization statement.
  364.  *    Ex:
  365.  *        static Sync_Semaphore foo = Sync_SemInitStatic("foo");
  366.  *
  367.  * Results:
  368.  *    None.
  369.  *
  370.  * Side effects:
  371.  *    None.
  372.  *
  373.  *----------------------------------------------------------------------
  374.  */
  375.  
  376.  
  377. #define Sync_SemInitStatic(name) {0}
  378.  
  379.  
  380.  
  381. /*
  382.  *----------------------------------------------------------------------
  383.  *
  384.  * Sync_SemInitDynamic --
  385.  *
  386.  *    Initializes the fields of a semaphore during program execution.
  387.  *    Ex:
  388.  *        Sync_SemInitDynamic(foo,"foo");
  389.  *
  390.  * Results:
  391.  *    None.
  392.  *
  393.  * Side effects:
  394.  *    None.
  395.  *
  396.  *----------------------------------------------------------------------
  397.  */
  398.  
  399.  
  400. #define Sync_SemInitDynamic(sem,semName) \
  401.     { \
  402.     (sem)->value =  0;    }
  403.  
  404.  
  405. /*
  406.  *----------------------------------------------------------------------
  407.  *
  408.  * Sync_LockInitStatic --
  409.  *
  410.  *    Initializes the fields of a lock in an initialization statement.
  411.  *    Ex:
  412.  *        static Sync_Lock foo = Sync_LockInitStatic("foo");
  413.  *
  414.  * Results:
  415.  *    None.
  416.  *
  417.  * Side effects:
  418.  *    None.
  419.  *
  420.  *----------------------------------------------------------------------
  421.  */
  422.  
  423. #define Sync_LockInitStatic(name) {0}
  424.  
  425.  
  426. /*
  427.  *----------------------------------------------------------------------
  428.  *
  429.  * Sync_LockInitDynamic --
  430.  *
  431.  *    Initializes the fields of a lock during program execution.
  432.  *    Ex:
  433.  *        Sync_LockInitDynamic(foo,"foo");
  434.  *
  435.  * Results:
  436.  *    None.
  437.  *
  438.  * Side effects:
  439.  *    None.
  440.  *
  441.  *----------------------------------------------------------------------
  442.  */
  443.  
  444.  
  445. #define Sync_LockInitDynamic(lock, name) {(lock)->inUse = (lock)->waiting = 0;}
  446.  
  447. #endif /* _SYNC */
  448.  
  449.